#include <iostream>
#include <string_view>
#include <vector>

namespace cpp23 {

// 用于检查函数是否在编译时求值的帮助函数
consteval bool is_constant_evaluated_cxx23() {
  return true;
}

// 常数求值上下文检测函数
constexpr bool is_constant_context() {
  if consteval {  // C++23新特性
    return true;  // 编译时执行
  } else {
    return false; // 运行时执行
  }
}

// 用于演示C++20的is_constant_evaluated()功能
constexpr bool is_constant_context_cxx20() {
  if (std::is_constant_evaluated()) {
    return true;  // 编译时执行
  } else {
    return false; // 运行时执行
  }
}

// 一个根据调用上下文提供不同实现的函数
constexpr int factorial(int n) {
  if consteval {
    // 编译时版本 - 递归实现
    if (n <= 1) return 1;
    return n * factorial(n - 1);
  } else {
    // 运行时版本 - 循环实现
    int result = 1;
    for (int i = 2; i <= n; ++i) {
      result *= i;
    }
    return result;
  }
}

// 根据上下文执行不同操作的函数
constexpr std::string_view get_context_message() {
  if consteval {
    return "编译时调用";
  } else {
    return "运行时调用";
  }
}

// 根据编译时/运行时上下文返回不同类型的示例
constexpr auto get_value() {
  if consteval {
    // 在编译时返回一个编译期常量
    return 42;
  } else {
    // 在运行时返回一个从用户输入获取的值
    int value;
    std::cout << "请输入一个值: ";
    std::cin >> value;
    return value;
  }
}

// 使用if consteval进行编译时断言
// 注意：为了演示代码能够编译，这里使用模板特化来实现编译时检查
template<bool Condition>
constexpr void compile_time_assert_impl() {
  static_assert(Condition, "编译时断言失败");
}

template<>
constexpr void compile_time_assert_impl<false>() {
  // 如果条件为false，这里不会实例化，因为static_assert会失败
}

constexpr void compile_time_assert(bool condition, const char* message) {
  if consteval {
    // 编译时检查
    if constexpr (true) {  // 这里需要用constexpr if
      // 对于演示目的，我们注释掉实际的断言
      // 实际使用时，应该确保condition是编译时常量
      (void)condition;
      (void)message;
    }
  } else {
    // 运行时不做任何检查
    (void)condition;
    (void)message;
  }
}

// 使用if consteval优化复杂计算
constexpr double calculate_pi(int iterations) {
  if consteval {
    // 编译时使用更精确但可能较慢的算法
    double result = 0.0;
    for (int i = 0; i < iterations; i++) {
      double term = 1.0 / (2 * i + 1);
      if (i % 2 == 0) {
        result += term;
      } else {
        result -= term;
      }
    }
    return result * 4;
  } else {
    // 运行时使用预计算值或更快的算法
    return 3.14159265358979323846;
  }
}

} // namespace cpp23

void demonstrate_if_consteval() {
  using namespace cpp23;

  std::cout << "C++23 'if consteval' 特性演示\n";
  std::cout << "==============================\n\n";

  // 运行时上下文检测
  std::cout << "1. 上下文检测：\n";
  constexpr bool compile_time = is_constant_context();  // 编译时
  bool runtime = is_constant_context();  // 运行时
  
  std::cout << "编译时求值结果: " << (compile_time ? "是" : "否") << "\n";
  std::cout << "运行时求值结果: " << (runtime ? "是" : "否") << "\n\n";

  // 与C++20的比较
  std::cout << "2. 与C++20的std::is_constant_evaluated()比较：\n";
  constexpr bool compile_time_cxx20 = is_constant_context_cxx20();
  bool runtime_cxx20 = is_constant_context_cxx20();
  
  std::cout << "C++20 编译时求值结果: " << (compile_time_cxx20 ? "是" : "否") << "\n";
  std::cout << "C++20 运行时求值结果: " << (runtime_cxx20 ? "是" : "否") << "\n\n";

  // 阶乘函数示例
  std::cout << "3. 根据上下文使用不同实现的阶乘函数：\n";
  constexpr int fact5_compile = factorial(5);  // 使用递归实现
  int fact5_runtime = factorial(5);           // 使用循环实现
  
  std::cout << "5的阶乘 (编译时计算): " << fact5_compile << "\n";
  std::cout << "5的阶乘 (运行时计算): " << fact5_runtime << "\n\n";

  // 根据上下文的消息
  std::cout << "4. 根据上下文返回不同消息：\n";
  constexpr auto compile_msg = get_context_message();
  auto runtime_msg = get_context_message();
  
  std::cout << "消息1: " << compile_msg << "\n";
  std::cout << "消息2: " << runtime_msg << "\n\n";

  // 演示PI的计算
  std::cout << "5. 优化复杂计算：\n";
  constexpr double pi_compile = calculate_pi(1000); // 编译时计算
  double pi_runtime = calculate_pi(1000);           // 运行时使用预计算值
  
  std::cout << "π值 (编译时计算): " << pi_compile << "\n";
  std::cout << "π值 (运行时计算): " << pi_runtime << "\n\n";

  std::cout << "C++23 'if consteval' 的优势：\n";
  std::cout << "1. 语法更清晰，直接表达意图\n";
  std::cout << "2. 可以根据编译时/运行时上下文提供不同的实现\n";
  std::cout << "3. 可以优化编译时计算性能\n";
  std::cout << "4. 比C++20的std::is_constant_evaluated()更直观\n";
  std::cout << "5. 允许在同一函数中使用不同的算法或数据结构\n";
  std::cout << "6. 简化了编译时断言和验证\n";
} 